package org.bootstrap.service.Impl;

import cn.hutool.core.lang.Console;
import cn.hutool.core.util.*;
import cn.hutool.http.HtmlUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import org.bootstrap.entity.HtmlContent;
import org.bootstrap.entity.WorkType;
import org.bootstrap.mapper.ListMapper;
import org.bootstrap.service.ListService;
import org.bootstrap.tool.BooleanOptional;
import org.bootstrap.tool.HtmlRepository;
import org.bootstrap.tool.RedisTool;
import org.bootstrap.tool.Tool;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.sql.SQLNonTransientException;
import java.util.*;

@Lazy
@SuppressWarnings("unused")
@Service
@PropertySource("classpath:application.yml")
public class ListServiceImpl implements ListService {
    @Resource
    private FileServiceImpl fileService;
    @Resource
    private ListMapper listMapper;

    @Resource
    private UserServiceImpl userService;

    @Resource
    private Tool tool;
    @Value("${local-disk.root}")
    private String localDiskRoot;
    @Resource
    private RedisTool redisTool;

    @Value("${config.list-max-count}")
    private int setup;

    @Value("${local-disk.img_common}")
    private String imgCommon;

    @Resource
    private HtmlRepository htmlRepository;

    @Override
    public JSONObject get_detail(String id, String page) {
        int _page = 0;
        if (StrUtil.isNotEmpty(page)) { // 转页码
            try {
                _page = NumberUtil.parseInt(page);
            } catch (Exception e) {
                Console.error(e.getMessage());
            }
        }
        int[] index = PageUtil.transToStartEnd(_page, setup);
        HashMap<String, Object> map = new HashMap<>();
        map.put("id", id);
        map.put("start", index[0]);
        map.put("end", setup);
        LinkedList<HashMap<String, Object>> list = listMapper.get_detail(map);
        list.forEach(every -> {
            Object content_id = every.getOrDefault("content_id", null);
            if (content_id != null) {
                String str_id = StrUtil.toString(content_id);
                JSONObject html = content_get(str_id);
                every.put("rich_content", html);
            }
        });
        JSONObject res = JSONUtil.createObj();
        res.putOpt("list", list).putOpt("total", list.size()) // 总数
                .putOpt("setup", setup).putOpt("all", get_list_count_by_id(id)); // 分批加载的数量
        return res;
    }


    public Integer get_list_count_by_id(String id) {
        String _id = "tag_id-" + id;
        int rows = 0;
        // 该数量要写入redis 缓存 只在第一次查询，后续返回就直接返回缓存 避免频繁查询数据库
        if (StrUtil.isNotEmpty(_id)) {
            if (redisTool.hasKey(_id)) { //取缓存
                String _num = redisTool.get_string(_id);
                if (StrUtil.isNotEmpty(_num)) {
                    try {
                        rows = NumberUtil.parseInt(_num);
                    } catch (Exception ignore) {
                        Console.error("数字转换失败");
                    }
                }
            } else { // 写缓存
                rows = listMapper.get_list_count_by_id(id);
                redisTool.save_string(_id, StrUtil.toString(rows));
            }
        }
        return rows;
    }

    @Override
    public LinkedList<HashMap<String, Object>> get_sel_options() {
        return listMapper.get_sel_options();
    }

    @Override
    public JSONObject push(HashMap<String, Object> _form) {
        JSONObject json = JSONUtil.createObj();
        int code;
        String msg;
        if (_form.isEmpty()) {
            code = 500;
            msg = "表单数据有误";
        } else {
            Object obj_name = _form.getOrDefault("name", null);
            String listId;
            if (Objects.nonNull(obj_name)
                    && StrUtil.isNotEmpty(obj_name.toString()) &&
                    StrUtil.isNotEmpty(listId = tool.getIdFromName(obj_name.toString()))) {
                if (_form.containsKey("menu_id") && StrUtil.isNotEmpty(StrUtil.toString(_form.get("menu_id")))) {
                    String self_id = RandomUtil.randomString(6);
                    String children_id = RandomUtil.randomString(6);
                    _form.put("self_id", self_id); // 自身ID
                    _form.put("children_id", children_id);// 子单ID
                    _form.put("list_id", listId);
                    HashMap<String, String> opt = new HashMap<>();// 获取当前操作用户
                    opt.put("token", StrUtil.toString(_form.get("token")));
                    JSONObject user_info = userService.user_info(opt, true);
                    if (!Objects.isNull(user_info) && user_info.getBool("login")) {
                        Object assign = _form.get("assign");
                        if (!Objects.isNull(assign)) {
                            String str_assign = StrUtil.toString(assign);
                            String arr_assign = tool.StrArrayToStr(str_assign);
                            _form.replace("assign", arr_assign);
                        } else {
                            _form.replace("assign", null);
                        }
                        _form.put("user_id", user_info.get("user_id"));
                        _form.put("author_id", user_info.get("author_id"));
                        _form.remove("token"); // 移除token
                        int rows = listMapper.push(_form);
                        if (rows > 0) {
                            code = 200;
                            msg = "添加成功";
                        } else {
                            code = 500;
                            msg = "添加失败";
                        }
                    } else {
                        code = 400;
                        msg = "未登录";
                    }
                } else {
                    code = 400;
                    msg = "指向菜单为空";
                }
            } else {
                code = 400;
                msg = "名字中需包含单号！";
            }

        }
        json.putOpt("code", code).putOpt("msg", msg);
        return json;
    }

    @Override
    public JSONObject content_push(String listId, String content) {
        int code;
        String msg;
        JSONObject json = JSONUtil.createObj();
        if (StrUtil.isEmpty(listId) || StrUtil.isEmpty(content)) {
            code = 500;
            msg = "内容为空";
        } else {
            String hasId = listMapper.hasUniqueId(listId); // 判断是否已有富文本id
            if (StrUtil.isNotEmpty(hasId)) {
                code = 200;
                msg = "修改成功";
                HtmlContent htmlContent = new HtmlContent(hasId, RandomUtil.randomString(5), content);
                if (htmlRepository.existsById(hasId)) {
                    htmlRepository.deleteById(hasId); // 删除原来的
                }
                HtmlContent save = htmlRepository.save(htmlContent);
            } else {
                String unique_id = RandomUtil.randomString(10);
                HtmlContent htmlContent = new HtmlContent(unique_id, RandomUtil.randomString(5), content);
                HtmlContent save = htmlRepository.save(htmlContent);
                int row = listMapper.modify_content_id(unique_id, listId);
                code = (row > 0) ? 200 : 500;
                msg = (row > 0) ? "修改成功" : "修改失败";
            }
        }
        json.putOpt("code", code)
                .putOpt("msg", msg);
        return json;
    }

    @Override
    public JSONObject content_get(String id) {
        int code;
        String content = null;
        JSONObject json = JSONUtil.createObj();
        Optional<HtmlContent> data = htmlRepository.findById(id);
        if (data.isPresent()) {
            HtmlContent res_data = data.get();
            if (ObjUtil.isNotNull(res_data)) {
                code = 200;
                content = res_data.getContent();
            } else {
                code = 502;
            }
        } else {
            code = 500;
        }
        json.putOpt("code", code).putOpt("content", content);
        return json;
    }

    public JSONObject rt_img_push(MultipartFile[] fileList) {
        JSONObject json = JSONUtil.createObj();
        JSONObject data = JSONUtil.createObj();
        fileService.whiteImageToDisk(fileList, localDiskRoot + "/" + imgCommon, ls -> {
            if (ls.isEmpty()) {
                json.putOpt("errno", 1);
                return;
            }
            ls.forEach(ev -> {
                data.putOpt("url", fileService.getUri() + "/media/" + ev);
                json.putOpt("errno", 0).putOpt("data", data);
            });
        });
        return json;
    }

    @Override
    public JSONObject get_children(String id) {
        return null;
    }

    @Override
    public JSONObject get_children_work_type() {
        ArrayList<WorkType> workType = listMapper.get_children_work_type();
        JSONObject obj = JSONUtil.createObj();
        obj.putOpt("list", workType);
        return obj;
    }

    @Override
    public JSONObject add_children(HashMap<String, Object> params) {
        JSONObject res = JSONUtil.createObj();
        if (params.isEmpty()) {
            res.putOpt("code", 400).putOpt("msg", "参数异常");
        } else if (params.containsKey("token") && params.containsKey("param")) {
            // 验证token 是否生效
            HashMap<String, String> tokenMap = new HashMap<>();
            tokenMap.put("token", (String) params.getOrDefault("token", null));
            JSONObject user_verity = userService.user_verity(tokenMap);
            if (!Objects.isNull(user_verity)) {
                if (user_verity.containsKey("login") && user_verity.getBool("login")) { // token 过期，提示重新登录
                    res.putOpt("code", 300).putOpt("msg", "登录过期，请重新登陆");
                } else {
                    JSONObject user_info = user_verity.getJSONObject("user_info");
                    BooleanOptional.of(Objects.isNull(user_info)).isFalse(t -> { // 验证信息通过
                        String user_id = user_info.getStr("user_id"); // 获取用户id
                        Object obj_param = params.get("param");
                        if (obj_param != null) {
                            JSONObject toJson = JSONUtil.parseObj(obj_param);
                            HashMap<String, Object> formData = new HashMap<>(toJson); // 遍历
                            Object parent_id = formData.getOrDefault("parent_id", null);
                            String self_id = RandomUtil.randomString(8); // 自身id
                            if (Objects.nonNull(parent_id)) {
                                formData.put("self_id", self_id); // 需求自身id
                                formData.put("author_id", user_id);// 建单人id
                                Object name = formData.getOrDefault("name", null);
                                String list_id = tool.getIdFromName(name.toString());
                                formData.put("list_id", list_id);
                                try {
                                    int rows = listMapper.add_children(formData);
                                    res.putOpt("code", rows > 0 ? 200 : 500).putOpt("msg", rows > 0 ? "添加成功" : "添加失败");
                                } catch (Exception e) {
                                    res.putOpt("code", 500)
                                            .putOpt("msg", "单子已存在");
                                }

                            } else {
                                res.putOpt("code", 501)
                                        .putOpt("msg", "文件夹不存在");
                            }
                        } else {
                            res.putOpt("code", 503)
                                    .putOpt("msg", "表单数据异常");
                        }
                    }).isTrue(r -> {
                        // 验证token 失败
                        res.putOpt("code", 401).putOpt("msg", "用户信息异常，请重新登陆");
                    });
                }
            }
        } else {
            res.putOpt("code", 400).putOpt("msg", "参数异常");
        }
        return res;
    }

    @Override
    public void Update_Rec_Log() {

    }

    @Override
    public HashMap<String, Object> get_children_detail(String id) {
        if (StrUtil.isNotEmpty(id)) {
            String safe_param = HtmlUtil.filter(id); // 过滤xss 参数
            return listMapper.query_children(safe_param);
        } else {
            return null;
        }
    }
}
